package CCN::Ethernet::generate;
# (c) 2007, Stephane Alnet
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
use strict; use warnings;

use CCN::Core::FileTools;
use CCN::Ethernet::probe;
use configuration;

sub get_template($)
{
    my $what = shift;
    return CCN::Core::FileTools::content_of("$configuration::perl_base/CCN/Ethernet/templates/$what");
}

sub print_config($$)
{
    my ($what,$content) = @_;
    CCN::Core::FileTools::print_to("$configuration::html_base/config/$what",$content);
}

sub ipv4_to_binary($)
{
    my $v = shift;
    return 0 if not defined $v or $v !~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
    return ($1<<24) | ($2<<16) | ($3<<8) | $4;
}

sub binary_to_ipv4($)
{
    my $v = int(shift);
    return sprintf("%d.%d.%d.%d", ($v>>24)&0xff, ($v>>16)&0xff, ($v>>8)&0xff, $v&0xff);
}

sub run($)
{
    my $T = shift;

    mkdir "$configuration::html_base/config/etc";
    mkdir "$configuration::html_base/config/etc/default";
    mkdir "$configuration::html_base/config/etc/network";
    mkdir "$configuration::html_base/config/etc/dhcp3";

    my @interfaces = CCN::Ethernet::probe::interfaces();
    my @if_names = map { $_->{if_name} } @interfaces;

    my @dhcp_server_interfaces = qw(eth0);
    for my $if_name (@if_names)
    {
        my $inuse = defined($T->{"${if_name}_mode"}) && ($T->{"${if_name}_mode"} ne 'unused');
        $T->{"${if_name}_mode_inuse"} = $inuse;

        $T->{"${if_name}_mode_static"} = 
            defined($T->{"${if_name}_mode"}) && ($T->{"${if_name}_mode"} eq 'static');
        my $netaddr = 
            ipv4_to_binary($T->{"${if_name}_ipv4_address"})
            & ipv4_to_binary($T->{"${if_name}_ipv4_netmask"});

        $T->{"${if_name}_ipv4_netaddr"} = binary_to_ipv4($netaddr);

        # DHCP: assume the netmask is never smaller than /24
        $T->{"${if_name}_ipv4_dhcp_start"} = binary_to_ipv4($netaddr+100); 
        $T->{"${if_name}_ipv4_dhcp_end"}   = binary_to_ipv4($netaddr+199); 

        my $dhcp_server = $T->{"${if_name}_dhcp_server"};
        push @dhcp_server_interfaces, $if_name
            if $inuse and defined $dhcp_server and $dhcp_server eq 'yes';
    }
    $T->{dhcp_server_interfaces} = join(' ',@dhcp_server_interfaces);


    # XXX Need to add the data interfaces (e.g. HDLC, PPP, etc.)


    my %files = (
        'interfaces' => 'etc/network/interfaces',
        'iptables-rules' => 'etc/network/iptables-rules',
        'dhcpd.conf' => 'etc/dhcp3/dhcpd.conf',
        'default_dhcp3-server' => 'etc/default/dhcp3-server',
    );

    for my $f (keys %files)
    {
        my $tmpl = new HTML::Template(
            filename => "$configuration::perl_base/CCN/Ethernet/templates/$f",
            die_on_bad_params => 0, global_vars => 1);
        $tmpl->param(%{$T});
        print_config($files{$f},$tmpl->output);
    }

    # Everything went fine
    return '';
}

1;